Skip to content

fix: add back sub-rows onto aggregate context#6421

Merged
KevinVandy merged 5 commits into
betafrom
aggregation-sub-row-context
Jul 15, 2026
Merged

fix: add back sub-rows onto aggregate context#6421
KevinVandy merged 5 commits into
betafrom
aggregation-sub-row-context

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Jul 15, 2026

Copy link
Copy Markdown
Member

🎯 Changes

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

Summary by CodeRabbit

  • Improvements

    • Standardized aggregation terminology around sub-rows, including updated merge callback inputs.
    • Aggregations now support depth-aware selection and can merge immediate grouped sub-rows with improved numeric and min/max/extent edge-case handling.
    • Updated aggregation value retrieval to an options-based API ({ rows, maxDepth }) and added column-level maxAggregationDepth (defaulting to 0).
    • Added a new table API to expose maximum sub-row depth.
  • Examples

    • Updated aggregation footers in framework examples to use the new options-based call signature.
  • Tests

    • Updated and expanded aggregation/grouping tests for the new options API, depth-aware caching, and revised merge contract.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5569dfaf-43e6-4543-9600-f62e2cc60888

📥 Commits

Reviewing files that changed from the base of the PR and between bb60d4e and 394a1af.

📒 Files selected for processing (83)
  • docs/framework/alpine/guide/aggregation.md
  • docs/framework/angular/guide/aggregation.md
  • docs/framework/angular/guide/migrating.md
  • docs/framework/ember/guide/aggregation.md
  • docs/framework/lit/guide/aggregation.md
  • docs/framework/lit/guide/migrating.md
  • docs/framework/preact/guide/aggregation.md
  • docs/framework/preact/guide/migrating.md
  • docs/framework/react/guide/aggregation.md
  • docs/framework/react/guide/migrating.md
  • docs/framework/solid/guide/aggregation.md
  • docs/framework/solid/guide/migrating.md
  • docs/framework/svelte/guide/aggregation.md
  • docs/framework/svelte/guide/migrating.md
  • docs/framework/vanilla/guide/aggregation.md
  • docs/framework/vue/guide/aggregation.md
  • docs/framework/vue/guide/migrating.md
  • docs/guide/aggregation.md
  • docs/guide/row-models.md
  • docs/guide/rows.md
  • docs/guide/worker-row-models.md
  • docs/reference/index/functions/constructAggregationFn.md
  • docs/reference/index/functions/createFacetedMinMaxValues.md
  • docs/reference/index/functions/createFacetedUniqueValues.md
  • docs/reference/index/index.md
  • docs/reference/index/interfaces/AggregationContext.md
  • docs/reference/index/interfaces/AggregationFnDef.md
  • docs/reference/index/interfaces/AggregationFnDescriptor.md
  • docs/reference/index/interfaces/AggregationMergeContext.md
  • docs/reference/index/interfaces/AggregationValueContext.md
  • docs/reference/index/interfaces/AggregationValueOptions.md
  • docs/reference/index/interfaces/AggregationValueResult.md
  • docs/reference/index/interfaces/Cell_Aggregation.md
  • docs/reference/index/interfaces/ColumnDef_Aggregation.md
  • docs/reference/index/interfaces/Column_Aggregation.md
  • docs/reference/index/interfaces/ResolvedAggregationFn.md
  • docs/reference/index/interfaces/RowModelFns_Aggregation.md
  • docs/reference/index/interfaces/RowModelFns_All.md
  • docs/reference/index/interfaces/Row_Aggregation.md
  • docs/reference/index/interfaces/TableOptions_Aggregation.md
  • docs/reference/index/interfaces/Table_Core.md
  • docs/reference/index/interfaces/Table_Internal.md
  • docs/reference/index/interfaces/Table_Rows.md
  • docs/reference/index/type-aliases/AggregationFnListItem.md
  • docs/reference/index/type-aliases/AggregationFnOption.md
  • docs/reference/index/type-aliases/AggregationFnRef.md
  • docs/reference/index/type-aliases/AggregationResult.md
  • docs/reference/index/type-aliases/AggregationResultOf.md
  • docs/reference/index/type-aliases/BuiltInAggregationFn.md
  • docs/reference/index/type-aliases/ColumnAggregationValue.md
  • docs/reference/index/type-aliases/CustomAggregationFns.md
  • docs/reference/index/type-aliases/ExtractAggregationFnKeys.md
  • docs/reference/index/variables/aggregationFn_count.md
  • docs/reference/index/variables/aggregationFn_extent.md
  • docs/reference/index/variables/aggregationFn_first.md
  • docs/reference/index/variables/aggregationFn_last.md
  • docs/reference/index/variables/aggregationFn_max.md
  • docs/reference/index/variables/aggregationFn_mean.md
  • docs/reference/index/variables/aggregationFn_median.md
  • docs/reference/index/variables/aggregationFn_min.md
  • docs/reference/index/variables/aggregationFn_sum.md
  • docs/reference/index/variables/aggregationFn_unique.md
  • docs/reference/index/variables/aggregationFn_uniqueCount.md
  • docs/reference/index/variables/aggregationFns.md
  • docs/reference/index/variables/coreRowsFeature.md
  • docs/reference/static-functions/functions/aggregateColumnValue.md
  • docs/reference/static-functions/functions/cell_getIsAggregated.md
  • docs/reference/static-functions/functions/column_getAggregationFns.md
  • docs/reference/static-functions/functions/column_getAggregationValue.md
  • docs/reference/static-functions/functions/column_getAutoAggregationFn.md
  • docs/reference/static-functions/functions/formatAggregatedCellValue.md
  • docs/reference/static-functions/functions/normalizeAggregationRows.md
  • docs/reference/static-functions/functions/row_getAllCells.md
  • docs/reference/static-functions/functions/row_getAllCellsByColumnId.md
  • docs/reference/static-functions/functions/row_getParentRow.md
  • docs/reference/static-functions/functions/row_getParentRows.md
  • docs/reference/static-functions/functions/table_getMaxSubRowDepth.md
  • docs/reference/static-functions/functions/table_getRow.md
  • docs/reference/static-functions/functions/table_getRowId.md
  • docs/reference/static-functions/index.md
  • examples/react/aggregation/src/main.tsx
  • packages/table-core/skills/aggregation/SKILL.md
  • packages/table-core/skills/migrate-v8-to-v9/SKILL.md
 ___________________________________________
< Crossing the tensor streams to find bugs. >
 -------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
📝 Walkthrough

Walkthrough

Aggregation now supports depth-limited row selection, immediate sub-row contexts, renamed merge payloads, depth-aware cached values, and a new maximum sub-row depth table API. Grouped aggregation, built-in functions, tests, and examples are updated for these contracts.

Changes

Depth-aware aggregation contracts and execution

Layer / File(s) Summary
Aggregation contracts and depth-aware execution
packages/table-core/src/features/aggregation/aggregationFeature.types.ts, packages/table-core/src/features/aggregation/aggregationFeature.utils.ts, packages/table-core/src/features/aggregation/aggregationFeature.ts
Aggregation requests use { rows, maxDepth }; contexts expose immediate subRows; traversal, aggregation, and cache validation are depth-aware.

Maximum row-depth API

Layer / File(s) Summary
Expose maximum sub-row depth
packages/table-core/src/core/rows/coreRowsFeature.ts, packages/table-core/src/core/rows/coreRowsFeature.types.ts, packages/table-core/src/core/rows/coreRowsFeature.utils.ts
The row feature exposes a memoized getMaxSubRowDepth() API that returns the deepest core-row depth.

Grouped aggregation and built-in merges

Layer / File(s) Summary
Update grouped aggregation and built-in merge functions
packages/table-core/src/features/column-grouping/createGroupedRowModel.ts, packages/table-core/src/features/aggregation/aggregationFns.ts
Grouped aggregation passes subRows and grouped rows, while built-in merges consume subRowResults and handle compatible range values.

Validation and example adoption

Layer / File(s) Summary
Validate and adopt the options-based API
packages/table-core/tests/..., examples/*/aggregation/...
Tests cover depth selection, cache invalidation, grouped contexts, merge payloads, and maximum row depth; aggregation examples pass rows through options objects.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Table
  participant column_getAggregationValue
  participant aggregateColumnValue
  participant AggregationFnDef
  Table->>column_getAggregationValue: request rows and maxDepth
  column_getAggregationValue->>aggregateColumnValue: pass resolved depth
  aggregateColumnValue->>AggregationFnDef: pass subRows and subRowResults
  AggregationFnDef-->>aggregateColumnValue: return aggregated value
  aggregateColumnValue-->>column_getAggregationValue: update depth-aware cache
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: restoring sub-rows on the aggregate context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch aggregation-sub-row-context

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jul 15, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 394a1af

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 4m 18s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 22s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-15 19:39:51 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jul 15, 2026

Copy link
Copy Markdown
More templates

@tanstack/alpine-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/alpine-table@6421

@tanstack/angular-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table@6421

@tanstack/angular-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table-devtools@6421

@tanstack/ember-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/ember-table@6421

@tanstack/lit-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/lit-table@6421

@tanstack/match-sorter-utils

npm i https://pkg.pr.new/TanStack/table/@tanstack/match-sorter-utils@6421

@tanstack/preact-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table@6421

@tanstack/preact-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table-devtools@6421

@tanstack/react-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table@6421

@tanstack/react-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table-devtools@6421

@tanstack/solid-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table@6421

@tanstack/solid-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table-devtools@6421

@tanstack/svelte-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/svelte-table@6421

@tanstack/table-core

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-core@6421

@tanstack/table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-devtools@6421

@tanstack/vue-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table@6421

@tanstack/vue-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table-devtools@6421

commit: 394a1af

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/table-core/src/features/aggregation/aggregationFeature.utils.ts (1)

284-291: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Help TypeScript narrow subRows.

TypeScript's control flow analysis does not narrow the type of subRows across closures or via the canMerge boolean variable assignment. Depending on the TypeScript compiler version and settings, subRows.map might trigger an Object is possibly 'undefined' error.

Consider explicitly including subRows in the if condition to appease the compiler.

♻️ Proposed refactor
-    if (canMerge && definition.merge) {
+    if (canMerge && subRows && definition.merge) {
       return definition.merge({
         ...context,
         subRowResults: subRows.map((row) =>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/src/features/aggregation/aggregationFeature.utils.ts`
around lines 284 - 291, Update the merge branch around the canMerge check to
explicitly require subRows before calling subRows.map. Preserve the existing
definition.merge guard and merge arguments, ensuring TypeScript can narrow
subRows as defined within the branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/table-core/src/features/aggregation/aggregationFns.ts`:
- Around line 169-174: Update the loop handling subRowResults in the aggregation
function to validate that extent is a defined array before reading extent[0] or
extent[1]. Skip invalid or missing extents, while preserving the existing
valueKind and undefined min/max filtering for valid ranges.

---

Nitpick comments:
In `@packages/table-core/src/features/aggregation/aggregationFeature.utils.ts`:
- Around line 284-291: Update the merge branch around the canMerge check to
explicitly require subRows before calling subRows.map. Preserve the existing
definition.merge guard and merge arguments, ensuring TypeScript can narrow
subRows as defined within the branch.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 91c08fdc-fc43-4a86-a5ac-6e920363e953

📥 Commits

Reviewing files that changed from the base of the PR and between b4a6a36 and 325894f.

📒 Files selected for processing (6)
  • packages/table-core/src/features/aggregation/aggregationFeature.types.ts
  • packages/table-core/src/features/aggregation/aggregationFeature.utils.ts
  • packages/table-core/src/features/aggregation/aggregationFns.ts
  • packages/table-core/src/features/column-grouping/createGroupedRowModel.ts
  • packages/table-core/tests/implementation/features/aggregation/aggregationFeature.test.ts
  • packages/table-core/tests/unit/fns/aggregationFns.test.ts

Comment on lines +169 to +174
for (let i = 0; i < subRowResults.length; i++) {
const extent = subRowResults[i]!
const min = extent[0]
const max = extent[1]
const valueKind = getRangeKind(min)
if (!valueKind || min === undefined || max === undefined) continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Missing null-guard on extent elements.

If subRowResults[i] evaluates to undefined (which can happen if a sub-row lacks the aggregation value or getSubRowResult returns undefined), destructuring extent[0] will cause a runtime crash: TypeError: Cannot read properties of undefined (reading '0').

Check if extent is a valid array before accessing its elements.

🛡️ Proposed fix to prevent runtime crash
     for (let i = 0; i < subRowResults.length; i++) {
-      const extent = subRowResults[i]!
-      const min = extent[0]
-      const max = extent[1]
+      const extent = subRowResults[i]
+      if (!Array.isArray(extent)) continue
+      const min = extent[0]
+      const max = extent[1]
       const valueKind = getRangeKind(min)
       if (!valueKind || min === undefined || max === undefined) continue
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (let i = 0; i < subRowResults.length; i++) {
const extent = subRowResults[i]!
const min = extent[0]
const max = extent[1]
const valueKind = getRangeKind(min)
if (!valueKind || min === undefined || max === undefined) continue
for (let i = 0; i < subRowResults.length; i++) {
const extent = subRowResults[i]
if (!Array.isArray(extent)) continue
const min = extent[0]
const max = extent[1]
const valueKind = getRangeKind(min)
if (!valueKind || min === undefined || max === undefined) continue
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/src/features/aggregation/aggregationFns.ts` around lines
169 - 174, Update the loop handling subRowResults in the aggregation function to
validate that extent is a defined array before reading extent[0] or extent[1].
Skip invalid or missing extents, while preserving the existing valueKind and
undefined min/max filtering for valid ranges.

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud is proposing a fix for your failed CI:

We updated all 10 aggregation example files to align with the PR's API change, which replaced the getAggregationValue(rows?) signature with getAggregationValue(options?) where rows are now passed as { rows: [...] }. Without this fix, every framework's aggregation example failed type-checking with TS2345 because a raw Row[] array is no longer assignable to AggregationValueOptions. These changes restore type correctness across all affected examples.

Tip

We verified this fix by re-running tanstack-angular-table-example-aggregation:build, tanstack-alpine-table-example-aggregation:test:types.

Warning

The suggested diff is too large to display here, but you can view it on Nx Cloud ↗


Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally DS7h-ftW2

Apply fix locally with your editor ↗   View interactive diff ↗



🎓 Learn more about Self-Healing CI on nx.dev

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

@KevinVandy
KevinVandy merged commit 66f7508 into beta Jul 15, 2026
10 checks passed
@KevinVandy
KevinVandy deleted the aggregation-sub-row-context branch July 15, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant